import re, sys

# Class which replaces XML entities in raw text with the corresponding
# Unicode character.
#
# Comments from Ben: This is garbage!  SAX and similar packages that are
# built into Python surely have functions to automatically do this.

from codecs import latin_1_decode

class pcl_tei_entities:

    def __init__(self):
        self.entity_code_dict = {
            "amp": 0x0026,
            "pound": 0x00A3,
            "aacute": 0x00E1,
            "ampersand": 0x0026,
            "Aacute": 0x00C1,
            "acirc": 0x00E2,
            "Acirc": 0x00C2,
            "agrave": 0x00E0,
            "Agrave": 0x00C0,
            "aring": 0x00E5,
            "Aring": 0x00C5,
            "atilde": 0x00E3,
            "Atilde": 0x00C3,
            "auml": 0x00E4,
            "Auml": 0x00C4,
            "aelig": 0x00E6,
            "AElig": 0x00C6,
            "ccedil": 0x00E7,
            "Ccedil": 0x00C7,
            "eth": 0x00F0,
            "ETH": 0x00D0,
            "eacute": 0x00E9,
            "Eacute": 0x00C9,
            "ecirc": 0x00EA,
            "Ecirc": 0x00CA,
            "egrave": 0x00E8,
            "Egrave": 0x00C8,
            "euml": 0x00EB,
            "Euml": 0x00CB,
            "iacute": 0x00ED,
            "Iacute": 0x00CD,
            "icirc": 0x00EE,
            "Icirc": 0x00CE,
            "igrave": 0x00EC,
            "Igrave": 0x00CC,
            "iuml": 0x00EF,
            "Iuml": 0x00CF,
            "ntilde": 0x00F1,
            "Ntilde": 0x00D1,
            "oacute": 0x00F3,
            "Oacute": 0x00D3,
            "ocirc": 0x00F4,
            "Ocirc": 0x00D4,
            "ograve": 0x00F2,
            "Ograve": 0x00D2,
            "oslash": 0x00F8,
            "Oslash": 0x00D8,
            "otilde": 0x00F5,
            "Otilde": 0x00D5,
            "ouml": 0x00F6,
            "Ouml": 0x00D6,
            "szlig": 0x00DF,
            "thorn": 0x00FE,
            "THORN": 0x00DE,
            "uacute": 0x00FA,
            "Uacute": 0x00DA,
            "ucirc": 0x00FB,
            "Ucirc": 0x00DB,
            "ugrave": 0x00F9,
            "Ugrave": 0x00D9,
            "uuml": 0x00FC,
            "Uuml": 0x00DC,
            "yacute": 0x00FD,
            "Yacute": 0x00DD,
            "yuml": 0x00FF,
            "abreve": 0x0103,
            "Abreve": 0x0102,
            "amacr": 0x0101,
            "Amacr": 0x0100,
            "aogon": 0x0105,
            "Aogon": 0x0104,
            "cacute": 0x0107,
            "Cacute": 0x0106,
            "ccaron": 0x010D,
            "Ccaron": 0x010C,
            "ccirc": 0x0109,
            "Ccirc": 0x0108,
            "cdot": 0x010B,
            "Cdot": 0x010A,
            "dcaron": 0x010F,
            "Dcaron": 0x010E,
            "dstrok": 0x0111,
            "Dstrok": 0x0110,
            "ecaron": 0x011B,
            "Ecaron": 0x011A,
            "edot": 0x0117,
            "Edot": 0x0116,
            "emacr": 0x0113,
            "Emacr": 0x0112,
            "eogon": 0x0119,
            "Eogon": 0x0118,
            "gacute": 0x01F5,
            "gbreve": 0x011F,
            "Gbreve": 0x011E,
            "Gcedil": 0x0122,
            "gcirc": 0x011D,
            "Gcirc": 0x011C,
            "gdot": 0x0121,
            "Gdot": 0x0120,
            "hcirc": 0x0125,
            "Hcirc": 0x0124,
            "hstrok": 0x0127,
            "Hstrok": 0x0126,
            "Idot": 0x0130,
            "Imacr": 0x012A,
            "imacr": 0x012B,
            "ijlig": 0x0133,
            "IJlig": 0x0132,
            "inodot": 0x0131,
            "iogon": 0x012F,
            "Iogon": 0x012E,
            "itilde": 0x0129,
            "Itilde": 0x0128,
            "jcirc": 0x0135,
            "Jcirc": 0x0134,
            "kcedil": 0x0137,
            "Kcedil": 0x0136,
            "kgreen": 0x0138,
            "lacute": 0x013A,
            "Lacute": 0x0139,
            "lcaron": 0x013E,
            "Lcaron": 0x013D,
            "lcedil": 0x013C,
            "Lcedil": 0x013B,
            "lmidot": 0x0140,
            "Lmidot": 0x013F,
            "lstrok": 0x0142,
            "Lstrok": 0x0141,
            "nacute": 0x0144,
            "Nacute": 0x0143,
            "eng": 0x014B,
            "ENG": 0x014A,
            "napos": 0x0149,
            "ncaron": 0x0148,
            "Ncaron": 0x0147,
            "ncedil": 0x0146,
            "Ncedil": 0x0145,
            "odblac": 0x0151,
            "Odblac": 0x0150,
            "Omacr": 0x014C,
            "omacr": 0x014D,
            "oelig": 0x0153,
            "OElig": 0x0152,
            "racute": 0x0155,
            "Racute": 0x0154,
            "rcaron": 0x0159,
            "Rcaron": 0x0158,
            "rcedil": 0x0157,
            "Rcedil": 0x0156,
            "sacute": 0x015B,
            "Sacute": 0x015A,
            "scaron": 0x0161,
            "Scaron": 0x0160,
            "scedil": 0x015F,
            "Scedil": 0x015E,
            "scirc": 0x015D,
            "Scirc": 0x015C,
            "tcaron": 0x0165,
            "Tcaron": 0x0164,
            "tcedil": 0x0163,
            "Tcedil": 0x0162,
            "tstrok": 0x0167,
            "Tstrok": 0x0166,
            "ubreve": 0x016D,
            "Ubreve": 0x016C,
            "udblac": 0x0171,
            "Udblac": 0x0170,
            "umacr": 0x016B,
            "Umacr": 0x016A,
            "uogon": 0x0173,
            "Uogon": 0x0172,
            "uring": 0x016F,
            "Uring": 0x016E,
            "utilde": 0x0169,
            "Utilde": 0x0168,
            "wcirc": 0x0175,
            "Wcirc": 0x0174,
            "ycirc": 0x0177,
            "Ycirc": 0x0176,
            "Yuml": 0x0178,
            "zacute": 0x017A,
            "Zacute": 0x0179,
            "zcaron": 0x017E,
            "Zcaron": 0x017D,
            "zdot": 0x017C,
            "Zdot": 0x017B,
            "agr": 0x03B1,
            "Agr": 0x0391,
            "bgr": 0x03B2,
            "Bgr": 0x0392,
            "ggr": 0x03B3,
            "Ggr": 0x0393,
            "dgr": 0x03B4,
            "Dgr": 0x0394,
            "egr": 0x03B5,
            "Egr": 0x0395,
            "zgr": 0x03B6,
            "Zgr": 0x0396,
            "eegr": 0x03B7,
            "EEgr": 0x0397,
            "thgr": 0x03B8,
            "THgr": 0x0398,
            "igr": 0x03B9,
            "Igr": 0x0399,
            "kgr": 0x03BA,
            "Kgr": 0x039A,
            "lgr": 0x03BB,
            "Lgr": 0x039B,
            "mgr": 0x03BC,
            "Mgr": 0x039C,
            "ngr": 0x03BD,
            "Ngr": 0x039D,
            "xgr": 0x03BE,
            "Xgr": 0x039E,
            "ogr": 0x03BF,
            "Ogr": 0x039F,
            "pgr": 0x03C0,
            "Pgr": 0x03A0,
            "rgr": 0x03C1,
            "Rgr": 0x03A1,
            "sgr": 0x03C3,
            "Sgr": 0x03A3,
            "sfgr": 0x03C2,
            "tgr": 0x03C4,
            "Tgr": 0x03A4,
            "ugr": 0x03C5,
            "Ugr": 0x03A5,
            "phgr": 0x03C6,
            "PHgr": 0x03A6,
            "khgr": 0x03C7,
            "KHgr": 0x03A7,
            "psgr": 0x03C8,
            "PSgr": 0x03A8,
            "ohgr": 0x03C9,
            "OHgr": 0x03A9,
            "half": 0x00BD,
            "frac12": 0x00BD,
            "frac14": 0x00BC,
            "frac34": 0x00BE,
            "frac18": 0x215B,
            "frac38": 0x215C,
            "frac58": 0x215D,
            "frac78": 0x215E,
            "sup1": 0x00B9,
            "sup2": 0x00B2,
            "sup3": 0x00B3,
            "plus": 0x002B,
            "plusmn": 0x00B1,
            "equals": 0x003D,
            "gt": 0x003E,
            "divide": 0x00F7,
            "times": 0x00D7,
            "curren": 0x00A4,
            "pound": 0x00A3,
            "dollar": 0x0024,
            "cent": 0x00A2,
            "yen": 0x00A5,
            "num": 0x0023,
            "percnt": 0x0025,
            "ast": 0x2217,
            "commat": 0x0040,
            "lsqb": 0x005B,
            "bsol": 0x005C,
            "rsqb": 0x005D,
            "lcub": 0x007B,
            "horbar": 0x2015,
            "verbar": 0x007C,
            "rcub": 0x007D,
            "micro": 0x00B5,
            "ohm": 0x2126,
            "deg": 0x00B0,
            "ordm": 0x00BA,
            "ordf": 0x00AA,
            "sect": 0x00A7,
            "para": 0x00B6,
            "middot": 0x00B7,
            "larr": 0x2190,
            "rarr": 0x2192,
            "uarr": 0x2191,
            "darr": 0x2193,
            "copy": 0x00A9,
            "reg": 0x00AF,
            "trade": 0x2122,
            "brvbar": 0x00A6,
            "not": 0x00AC,
            "sung": 0x2669,
            "excl": 0x0021,
            "iexcl": 0x00A1,
            "quot": 0x0022,
            "apos": 0x0027,
            "lpar": 0x0028,
            "rpar": 0x0029,
            "comma": 0x002C,
            "lowbar": 0x005F,
            "hyphen": 0xE4F8,
            "period": 0x002E,
            "sol": 0x002F,
            "colon": 0x003A,
            "semi": 0x003B,
            "quest": 0x003F,
            "iquest": 0x00BF,
            "laquo": 0x00AB,
            "raquo": 0x00BB,
            "lsquo": 0x2018,
            "rsquo": 0x2019,
            "ldquo": 0x201C,
            "rdquo": 0x201D,
            "nbsp": 0x00A0,
            "shy": 0x00AD,
            "acute": 0x00B4,
            "breve": 0x02D8,
            "caron": 0x02C7,
            "cedil": 0x00B8,
            "circ": 0x2218,
            "dblac": 0x02DD,
            "die": 0x00A8,
            "dot": 0x02D9,
            "grave": 0x0060,
            "macr": 0x00AF,
            "ogon": 0x02DB,
            "ring": 0x02DA,
            "tilde": 0x007E,
            "uml": 0x00A8,
            "emsp": 0x2003,
            "ensp": 0x2002,
            "emsp13": 0x2004,
            "emsp14": 0x2005,
            "numsp": 0x2007,
            "puncsp": 0x2008,
            "thinsp": 0x2009,
            "hairsp": 0x200A,
            "mdash": 0x2014,
            "ndash": 0x2013,
            "dash": 0x2010,
            "blank": 0x2423,
            "hellip": 0x2026,
            "nldr": 0x2025,
            "frac13": 0x2153,
            "frac23": 0x2154,
            "frac15": 0x2155,
            "frac25": 0x2156,
            "frac35": 0x2157,
            "frac45": 0x2158,
            "frac16": 0x2159,
            "frac56": 0x215A,
            "incare": 0x2105,
            "block": 0x2588,
            "uhblk": 0x2580,
            "lhblk": 0x2584,
            "blk14": 0x2591,
            "blk12": 0x2592,
            "blk34": 0x2593,
            "marker": 0x25AE,
            "cir": 0x25CB,
            "squ": 0x25A1,
            "rect": 0x25AD,
            "utri": 0x25B5,
            "dtri": 0x25BF,
            "star": 0x22C6,
            "bull": 0x2022,
            "squf": 0x25AA,
            "utrif": 0x25B4,
            "dtrif": 0x25BE,
            "ltrif": 0x25C2,
            "rtrif": 0x25B8,
            "clubs": 0x2663,
            "diams": 0x2666,
            "hearts": 0x2665,
            "spades": 0x2660,
            "malt": 0x2720,
            "dagger": 0x2020,
            "Dagger": 0x2021,
            "check": 0x2713,
            "cross": 0x2717,
            "sharp": 0x266F,
            "flat": 0x266D,
            "male": 0x2642,
            "female": 0x2640,
            "phone": 0x260E,
            "telrec": 0x2315,
            "copysr": 0x2117,
            "caret": 0x2041,
            "lsquor": 0x201A,
            "ldquor": 0x201E,
            "fflig": 0xFB00,
            "filig": 0xFB01,
            "ffilig": 0xFB03,
            "ffllig": 0xFB04,
            "fllig": 0xFB02,
            "mldr": 0x2026,
            "rdquor": 0x201C,
            "rsquor": 0x2018,
            "vellip": 0x22EE,
            "hybull": 0x2043,
            "loz": 0x25CA,
            "lozf": 0x2726,
            "ltri": 0x25C3,
            "rtri": 0x25B9,
            "starf": 0x2605,
            "natur": 0x266E,
            "rx": 0x211E,
            "sext": 0x2736,
            "target": 0x2316,
            "dlcrop": 0x230D,
            "drcrop": 0x230C,
            "ulcrop": 0x230F,
            "urcrop": 0x230E,
            "boxh": 0x2500,
            "boxv": 0x2502,
            "boxur": 0x2514,
            "boxul": 0x2518,
            "boxdl": 0x2510,
            "boxdr": 0x250C,
            "boxvr": 0x251C,
            "boxhu": 0x2534,
            "boxvl": 0x2524,
            "boxhd": 0x252C,
            "boxvh": 0x253C,
            "boxvR": 0x255E,
            "boxhU": 0x2567,
            "boxvL": 0x2561,
            "boxhD": 0x2564,
            "boxvH": 0x256A,
            "boxH": 0x2550,
            "boxV": 0x2551,
            "boxUR": 0x2558,
            "boxUL": 0x255B,
            "boxDL": 0x2555,
            "boxDR": 0x2552,
            "boxVR": 0x255F,
            "boxHU": 0x2568,
            "boxVL": 0x2562,
            "boxHD": 0x2565,
            "boxVH": 0x256B,
            "boxVr": 0x2560,
            "boxHu": 0x2569,
            "boxVl": 0x2563,
            "boxHd": 0x2566,
            "boxVh": 0x256C,
            "boxuR": 0x2559,
            "boxUl": 0x255C,
            "boxdL": 0x2556,
            "boxDr": 0x2553,
            "boxUr": 0x255A,
            "boxuL": 0x255D,
            "boxDl": 0x2557,
            "boxdR": 0x2554
            }
        self.entity_char_dict = {}

        for ent, code in self.entity_code_dict.iteritems():
            try:
                self.entity_char_dict[ent] = latin_1_decode(chr(code),"utf8")[0]
            except ValueError,UnicodeEncodeError:
                self.entity_char_dict[ent] = unichr(code)

    def print_chars(self):
        for ent, code in self.entity_char_dict.iteritems():
            print ent, code

    def replace_entities(self,text):
        text = re.sub('&(?P<ent>[A-Za-z]+);', r'%(\?<ent>)', text)
        otext = text
        try:
            text = text % self.entity_code_dict
            return text
        except KeyError:
            print >>sys.stderr, "KeyError occurred at :", text
            print >>sys.stderr, "Original text was :", otext
        
